#include "Game.h"

#include "Ship.h"
#include "NetworkEvents.h"

CGame* CGame::m_pInstance = 0;

void CGame::run()
{
    
    std::cout << "ID_USER_PACKET_ENUM = " << ID_USER_PACKET_ENUM << std::endl;
    
    //Initialise the game
    init();
    
    //TODO: Replace this as it's a hack for now
    //      -----------------------------------
    std::cout << "Enter h to host, or any other key to join: ";
    
    char c;
    std::cin >> c;
    
    if (c == 'h')
        m_pMultiplayer->host(8, 60000);
    else {
        
        std::cout << "Enter host address: ";
        
        String sHostAddress;
        std::cin >> sHostAddress;
        
        if (sHostAddress == "l")
            m_pMultiplayer->join("localhost", 60000, 0);
        else
            //TODO: Eventually change client port from auto assign (0) to a constant if don't need to run two clients on same computer
            m_pMultiplayer->join(sHostAddress.c_str(), 60000, 0);
    
    }
    
    std::cout << "Multiplayer initialised, press enter to begin running the game" << std::endl;
    //      -----------------------------------
    
    //TODO: Think about how to do a createNetworkObject() with server (authority) checking and NetworkID generation or reception
    
    /*m_pMultiplayer->addNetworkObject(NetworkObject* pObject, CGame* pGame)
    {
        
        if (m_bIsServer) {
            
            
            
        }
        
    }
    
    CShip* pShip = new CShip();
    
    addGameObject(pShip);
    
    m_pMultiplayer->addObject(pShip);*/
    
    
    std::cin.get();
    std::cin.get();
    
    //TODO: Replace this with creating player avatars
    //		Although, could still add some non-player entities for good measure
    //		But, make sure that this is the right way and place to add the entities!
    /*if (m_pMultiplayer->isServer()) {
        
        for (int i=0;i<1;++i) {
            CCreateObjectEvent event("Ship");
            event.activate();
			CShip* pShip = (CShip*) event.getObject();
            //pShip->setVel(Vector(0.0002, 0, 0));
			pShip->setPos(Vector(0, i*5, 0));
            //pShip->setSize(2);
            
        }
        
    }*/
    
    //if (CMultiplayer::isServer()) {
        /*
        CShip* pShip = (CShip*) m_pMultiplayer->createNetworkObject("Ship");
        if (pShip) {
            addGameObject(pShip);
            pShip->setVel(Vector(0.001, 0, 0));
            //pShip->setAngle( );
        }
        
        CShip* pShip2 = (CShip*) m_pMultiplayer->createNetworkObject("Ship");
        if (pShip2) {
            addGameObject(pShip2);
            pShip2->setPos(Vector(0, 1, 0));
            pShip2->setSize(2);
            pShip2->setVel(Vector(-0.001, 0, 0));
            //pShip->setAngle( );
        }
        */
    //}
    
    bool bRunning = true;
    std::cout << "Beginning main loop" << std::endl;
    //The main game loop
    while (bRunning) {
        
        //Handle windows messages
        //-----------------------
        //Check for windows messages
		if (m_pRenderer->CheckMessages()) continue;
		
		//Make sure the renderer is currently active
		if (!m_pRenderer->isActive()) continue;

		//Check if the Engine has recieved a quit message
		if (m_pRenderer->isQuit()) bRunning = false;
        
		//Error checking
		int r = glGetError();
		if (r != GL_NO_ERROR) { std::cout << "OpenGL Error " << r << std::endl; }
		//------------------------
        
        //Gather input
        m_pInput->CheckInput();
        
        //Low level input commands
        //------------------------
        //Check for quit 
        if (m_pInput->KeyState(VK_ESCAPE) == true) bRunning = false;
        //if (Input.KeyState(VK_SPACE) == true) std::cout << Timer.getFPS() << std::endl;
        
        if (m_pInput->KeyState(VK_LBUTTON) && m_pInput->KeyState(VK_RBUTTON)) {
            //CameraTrans[2] += Input.MouseMoveVector()[1];
        }
        //------------------------
        
        if (m_pInput->KeyDown(VK_UP)) {
            if (!m_pMultiplayer->isServer()) {
                //std::cout << "Activating UP" << std::endl;
                //Create a test event to change the direction of the 0th object
                //CChangeDirEvent event(getMultiplayer()->getNetworkObject(0), Vector(0, 0.001, 0));
                CStartStopEvent clientEvent(KEY_UP, true);
                clientEvent.activate();       //Activate the event
            }
        }
        if (m_pInput->KeyDown(VK_DOWN)) {
            if (!m_pMultiplayer->isServer()) {
                CStartStopEvent clientEvent(KEY_DOWN, true);
                clientEvent.activate();       //Activate the event
            }
        }
        if (m_pInput->KeyDown(VK_LEFT)) {
            if (!m_pMultiplayer->isServer()) {
                CStartStopEvent clientEvent(KEY_LEFT, true);
                clientEvent.activate();       //Activate the event
            }
        }
        if (m_pInput->KeyDown(VK_RIGHT)) {
            if (!m_pMultiplayer->isServer()) {
                CStartStopEvent clientEvent(KEY_RIGHT, true);
                clientEvent.activate();       //Activate the event
            }
        }
        
        m_pTimer->Update();
        
        //if (m_pMultiplayer->isServer())
            update(m_pTimer->getElapsed() * 2.0);
        
        //if (!m_pMultiplayer->isServer())
            draw();
        
        //Draw a dot in the center of the screen for debugging
        //TODO: Remove this eventually
        glBindTexture(GL_TEXTURE_2D, 0);
        glBegin(GL_POINTS);
            glColor4f(1, 1, 1, 1);
            glVertex3f(0, 0, 0);
        glEnd();
        
        m_pMultiplayer->checkForPackets();
        
        if (m_pTimer->getTime() % 100 == 0) {
            
            m_pMultiplayer->update();
            
        }
        
        m_pRenderer->DrawScene(); 
        
    }
    
    //Shut down the game
    shutdown();
    
}

void CGame::init()
{
    
    //Create the rendering window
    m_pRenderer = new CRenderer();
    m_pRenderer->CreateRendererWindow("NetDodge", 400, 400, 32, false);
    
    //Create the input handler
    m_pInput = new CInput();
    
    //Create the timer
    m_pTimer = new CTimer();
    
    //Create the multiplayer manager
    m_pMultiplayer = new CMultiplayer(this);
    
    
}

void CGame::update(Scalar fTimeStep)
{
    
    for (int i=0;i<m_pObjects.size();++i) {
        
        m_pObjects[i]->update(fTimeStep);
        
    }
    
}

void CGame::draw()
{
    
    for (int i=0;i<m_pObjects.size();++i) {
        
        m_pObjects[i]->draw();
        
    }
    
}

void CGame::shutdown()
{
    
    delete m_pMultiplayer;        //TODO: Make sure this should be here
    delete m_pTimer;
    delete m_pInput;
    delete m_pRenderer;
    
}
